package com.zimug.courses.security.basic.config;

import com.zimug.courses.security.basic.auth.service.MyUserDetailsService;
import com.zimug.courses.security.basic.auth.service.RbacService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @Author: liull
 * @Description: 安全相关配置
 * @Date: Created in 22:15 2020/11/18
 * @Modified By:
 */
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyUserDetailsService userDetailsService;

    @Autowired
    private RbacService rbacService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 开器httpbasic认证
        // http.httpBasic()
        http.csrf()
                .disable()
                .formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/login")// 登录表单的action地址，也就是处理登陆的url
                .usernameParameter("username")
                .passwordParameter("password")
                .defaultSuccessUrl("/")
                // 对请求进行认证
                .and()
                .authorizeRequests()
                .antMatchers("/login.html", "/login").permitAll()
                // 替换为动态检查
                // .antMatchers("/", "biz1", "biz2")
                // .hasAnyAuthority("ROLE_user", "ROLE_admin")
                // // .antMatchers("/syslog", "/sysuser")
                // // .hasAnyRole("admin")
                // .antMatchers("/sysuser").hasAnyAuthority("/sys_user")
                // .antMatchers("/syslog").hasAnyAuthority("/sys_log")
                // .anyRequest().authenticated()// 除了以上配置之外其它请求认证后才能访问,权限范围越宽，越最后配置
                .anyRequest()
                // TODO 牛掰啊
                .access("@rbacService.hasPermission(authentication, request)")
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .invalidSessionUrl("/login.html");

    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // auth.inMemoryAuthentication()
        // .withUser("liull").password(passwordEncoder().encode("123456"))
        // .roles("user")
        // .and()
        // .withUser("admin").password(passwordEncoder().encode("admin"))
        // // .roles("admin")
        // .authorities("sys:log", "sys:user")
        // .and()
        // .passwordEncoder(passwordEncoder());
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/css/**", "/fonts", "/js/**", "/img/**");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
